package com.ddxz.photovoltaic.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ddxz.photovoltaic.configuration.PhotoVoltaicProperties;
import com.ddxz.photovoltaic.consts.PageDto;
import com.ddxz.photovoltaic.consts.PhotovoltaicData;
import com.ddxz.photovoltaic.entity.OutStationEntity;
import com.ddxz.photovoltaic.entity.StationEntity;
import com.ddxz.photovoltaic.feign.DdxzHttpUtils;
import com.ddxz.photovoltaic.mapper.StationMapper;
import com.ddxz.photovoltaic.service.SyncDataService;
import com.ddxz.tool.core.common.CommonUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Service;
import org.springframework.util.MultiValueMap;

import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.security.MessageDigest;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * class description
 *
 * @author 朱宗刚
 * @version 1.0.0
 * @date 2022/8/20
 */

@Service
public class SyncDataServiceImpl implements SyncDataService {
    private final PhotoVoltaicProperties properties;

    private final StationMapper mapper;

    public SyncDataServiceImpl(PhotoVoltaicProperties properties, StationMapper mapper, DdxzHttpUtils httpUtils) {
        this.properties = properties;
        this.mapper = mapper;
        this.httpUtils = httpUtils;
    }

    /**
     * 开启同步任务，记录
     */
    @Override
    public void syncData() {
        syncSatitionData();
        syncCollectorData();
        syncInverterData();
        syncEpmData();

    }

    private void syncSatitionData() {
        MultiValueMap<String, String> header = generatorHeader(PhotovoltaicData.STATION_LIST, new PageDto());
        JSONObject rst = httpUtils.doPost(PhotovoltaicData.JIN_LANG + PhotovoltaicData.STATION_LIST, header, new PageDto());

        JSONArray array = rst.getJSONObject("data").getJSONObject("page").getJSONArray("records");
        List<StationEntity> stations = new ArrayList<>(array.size());
        for(int i = 0; i < array.size(); ++i) {
            stations.add(array.getJSONObject(i).toJavaObject(StationEntity.class));
        }
        LOGGER.debug("{}", stations);
        MultiValueMap<String, String> headers = new HttpHeaders();
        headers.put("Content-type", Arrays.asList("application/json"));
        headers.put("accept", Arrays.asList("application/json"));
        for(StationEntity se : stations) {
            rst = httpUtils.doPost(properties.getSignalRow(), headers, getOutStationEntity(se));
            LOGGER.info("Header: {}\nbody: {}\nresult: {}", JSON.toJSONString(headers), getOutStationEntity(se), rst);
        }
    }

    private void syncCollectorData() {

    }

    private void syncInverterData() {

    }

    private void syncEpmData() {

    }

    private OutStationEntity getOutStationEntity(StationEntity se) {
        OutStationEntity entity = new OutStationEntity();
        entity.setCjrq(outSdf.format(new Date()));
        entity.setBwtysj(properties.getProductDate());
        entity.setDnwgfdl(0.0);
        entity.setDnygfdl(transformUnit(se.getYearEnergy(), se.getYearEnergyStr()));
        entity.setDrwgfdl(0.0);
        entity.setDrygfdl(transformUnit(se.getDayEnergy(), se.getDayEnergyStr()));
        entity.setDywgfdl(0.0);
        entity.setDyygfdl(transformUnit(se.getMonthEnergy(), se.getMonthEnergyStr()));
        entity.setGffdqyhh(properties.getGffdqyhh());
        entity.setId(CommonUtil.snowId().toString());
        entity.setJsdd(se.getAddr());
        entity.setJsddjwd(se.getLatitude() + "," + se.getLongitude());
        entity.setQymc(properties.getCompanyName());
        entity.setTyshxydm(properties.getCompaynCode());
        entity.setXmmc(properties.getProjectName());

        return entity;
    }

    private Double transformUnit(Double val, String unit) {
        if(null == val) {
            return val;
        }

        if(unit == null) {
            return val;
        }

        if("MWh".equalsIgnoreCase(unit)) {
            return val * 1000;
        }

        if("GMh".equalsIgnoreCase(unit)) {
            return val * 1.0E6;
        }

        if("TMh".equalsIgnoreCase(unit)) {
            return val * 1.0E9;
        }

        return val;
    }

    private MultiValueMap<String, String> generatorHeader(String path, PageDto args) {
        SimpleDateFormat sdf = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss 'GMT'", Locale.US);
        try {
            MultiValueMap<String, String> headers = new HttpHeaders();
            String date = sdf.format(new Date(System.currentTimeMillis() - 8*3600000L));
            headers.put("Date", Arrays.asList(date));
            headers.put("Content-Type", Arrays.asList("application/json"));
            MessageDigest md = MessageDigest.getInstance("MD5");
            String body = JSONObject.toJSONString(args);
            md.update(body.getBytes());
            String mbody = Base64.getEncoder().encodeToString(md.digest());
            headers.put("Content-MD5", Arrays.asList(mbody));
            String srcSign = "POST\n" + mbody + "\napplication/json\n" + date + "\n" + path;
            SecretKey secretKey = new SecretKeySpec(properties.getKeySecret().getBytes("UTF-8"), "HmacSHA1");
            Mac mac = Mac.getInstance("HmacSHA1");
            mac.init(secretKey);
            headers.put("Authorization", Arrays.asList("API " + properties.getKeyId() + ":" + Base64.getEncoder().encodeToString(mac.doFinal(srcSign.getBytes("UTF-8")))));

            return headers;
        } catch (Exception e) {
            LOGGER.error("生成秘钥失败path: {}, args: {}", path, args, e);
            return null;
        }
    }

    /**
     * 写入数据的日期事件格式
     */
    private SimpleDateFormat outSdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    private final DdxzHttpUtils httpUtils;

    private static final Logger LOGGER = LoggerFactory.getLogger(SyncDataServiceImpl.class);
}
